%%% @doc
%%% окно для запуска тестов
%%% @end
-module(server_ui).
-export([eventLoop/3, createWindow/2]).
-include_lib("wx/include/wx.hrl").
-include("definitions.hrl").

%% constants
-define(GRID_TESTS, 4).
-define(GRID, 3).
-define(BUTTON_START, 1).
-define(BUTTON_START_AUTO, 2).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% на экспорт
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

eventLoop(WxFrame, Grid, DeviceList) ->
  receive

    #wx{event = #wxClose{}} ->
      server_logic:dispose(),
      ok;

    #wx{id = ?BUTTON_START_AUTO, event = #wxCommand{type = command_button_clicked}} ->
      {DevList, Tests} = server_logic:runTestsAuto(),
      server_logic:runTests(DevList, Tests, self()),
      receive
        testsRunning ->
          server_logic:showTests(?DEVICES_LIMIT)%length(DeviceList)
      end,
      eventLoop(WxFrame, Grid, DevList);


    #wx{id = ?BUTTON_START, event = #wxCommand{type = command_button_clicked}} ->
      %Tests:: dict(int, int)
      Tests = getTestsFromGrid(Grid, length(DeviceList), dict:new()),
      server_logic:runTests(DeviceList, Tests, self()),
      receive
        testsRunning ->
          server_logic:showTests(length(DeviceList))
      end,
      eventLoop(WxFrame, Grid, DeviceList)
  end.

createWindow(DeviceList, TestIds) ->
  Wx = wx:new(),
  WxFrame = wxFrame:new(Wx, -1, "Главный экран"),
  wxFrame:setSize(WxFrame, {700, 1000}),
  wxFrame:connect(WxFrame, close_window),
  wxFrame:show(WxFrame),
  GridDevices = initControls(WxFrame, DeviceList, TestIds),
  {WxFrame, GridDevices}.

initControls(WxFrame, DeviceList, TestIds) ->
  initButtons(WxFrame),
  createGridTests(WxFrame, TestIds),
  createGridDevices(WxFrame, DeviceList, TestIds)
.

initButtons(WxFrame) ->
  ButtonRun = wxButton:new(WxFrame, ?BUTTON_START, [{label, "Запуск выбранных"}, {pos, {20, 530}}, {size, {270, 30}}]),
  Text = "Запустить " ++ integer_to_list(?DEVICES_LIMIT) ++ " тестов",
  ButtonRunAuto = wxButton:new(WxFrame, ?BUTTON_START_AUTO, [{label, Text}, {pos, {20, 580}}, {size, {270, 30}}]),
  wxFrame:connect(ButtonRun, command_button_clicked),
  wxFrame:connect(ButtonRunAuto, command_button_clicked)
.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% гриды
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

createGridTests(WxFrame, TestIds) ->
  Grid = wxGrid:new(WxFrame, ?GRID_TESTS, [{size, {400, 490}}, {pos, {20, 630}}]),
  Rows = length(TestIds),%{id = -1, bits = [], description = "default description"}).
  Columns = 3,
  wxGrid:createGrid(Grid, Rows, Columns),
  wxGrid:autoSizeRows(Grid),
  wxGrid:autoSizeColumns(Grid),
  wxGrid:setColSize(Grid, 0, 80), %id теста
  wxGrid:setColSize(Grid, 1, 80), %имя прибора
  wxGrid:setColSize(Grid, 2, 340), %тест
  wxGrid:setColLabelValue(Grid, 0, "id теста"),
  wxGrid:setColLabelValue(Grid, 1, "описание"),
  wxGrid:setColLabelValue(Grid, 2, "тест"),
  bindGridTests(Grid, TestIds, Rows),
  Grid.

bindGridTests(Grid, _, 0) -> Grid;

bindGridTests(Grid, [TestId | TestIds], N) ->
  Test = test_storage:getTest(TestId),

  wxGrid:setCellValue(Grid, {N - 1, 0}, integer_to_list(Test#testCase.id)),
  wxGrid:setCellValue(Grid, {N - 1, 1}, Test#testCase.description),
  wxGrid:setCellValue(Grid, {N - 1, 2}, lists:concat(Test#testCase.bits)),
  bindGridTests(Grid, TestIds, N - 1)
.

%грид с приборами
createGridDevices(WxFrame, DeviceList, TestIds) ->
  Grid = wxGrid:new(WxFrame, ?GRID, [{size, {400, 490}}, {pos, {20, 20}}]),
  Rows = length(DeviceList),
  Columns = 3,
  wxGrid:createGrid(Grid, Rows, Columns),
  wxGrid:autoSizeRows(Grid),
  wxGrid:autoSizeColumns(Grid),
  wxGrid:setColSize(Grid, 0, 80), %id прибора
  wxGrid:setColSize(Grid, 1, 80), %имя прибора
  wxGrid:setColSize(Grid, 2, 240), %тест
  wxGrid:setColLabelValue(Grid, 0, "id прибора"),
  wxGrid:setColLabelValue(Grid, 1, "описание"),
  wxGrid:setColLabelValue(Grid, 2, "тест"),
  bindGrid(Grid, DeviceList, TestIds, 0),
  Grid
.

%если все приборы перечислены
bindGrid(_, [], _, _) ->
  ok;

bindGrid(Grid, [{Name, Id} | T], TestIds, N) ->
  wxGrid:setCellValue(Grid, {N, 1}, Name),
  wxGrid:setCellValue(Grid, {N, 0}, integer_to_list(Id)),
  bindGrid(Grid, T, TestIds, N + 1).

%пройтись по всем строчкам, собрать номера тестов
%-spec getTestsFromGrid/3 :: (wxGrid(), integer(), dict(integer(), integer())) -> dict(integer(), integer()).
getTestsFromGrid(_, 0, Acc) ->
  Acc;

getTestsFromGrid(Grid, N, Acc) ->
  DeviceId = list_to_integer(wxGrid:getCellValue(Grid, {N - 1, 1})),%id прибора
  case wxGrid:getCellValue(Grid, {N - 1, 2}) of%id теста
    [] -> getTestsFromGrid(Grid, N - 1, Acc);
    Number ->
      {TestIdInt, _} = string:to_integer(Number),
      Dict = dict:append(DeviceId, TestIdInt, Acc),
      getTestsFromGrid(Grid, N - 1, Dict)
  end.